﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace AutomaticScrewLocking.domain.modbus.protocol.service.impl
{
    public class ModbusTCP : Modbus
    {
        // 事务 ID
        private ushort workId = 0;
        // 接收缓冲区大小
        public const int BUFFERSIZE = 2048;

        // IP 地址
        private string Ip;

        // 超时时间
        private int Timeout;

        // 存储解析后的IP地址
        public IPAddress IpAddress { get; set; }

        // 端口
        public int Port { get; set; }

        // Socket 客户端对象
        public Socket Client { get; set; }

        /// <summary>
        /// 建立 Modbus TCP 连接
        /// </summary>
        /// <param name="ip">ip地址</param>
        /// <param name="port">端口</param>
        /// <param name="errorMsg">错误信息</param>
        /// <param name="timeOut">超时时间</param>
        /// <returns></returns>
        public bool Connect(string ip, int port, out string errorMsg, int timeOut = 2000)
        {
            bool flag = false;
            errorMsg = string.Empty;
            try
            {
                Ip = ip;
                Port = port;
                Timeout = timeOut;

                flag = IPAddress.TryParse(ip, out var address);
                IpAddress = address;

                if (flag)
                {
                    flag = false;

                    // 创建 TCP Socket：IPv4 地址族、字节流类型、TCP 协议
                    Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    // 设置发送和接收超时策略（毫秒）
                    Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, timeOut);
                    Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, timeOut);

                    if (Client.Connected)
                    {
                        flag = true;
                    }
                }
                else
                {
                    errorMsg = "ip地址格式错误";
                }
            }
            catch(Exception ex)
            {
                errorMsg = ex.Message;
            }
            return flag;
        }

        /// <summary>
        /// 断开 Modbus TCP 连接
        /// </summary>
        /// <param name="errorMsg">错误信息</param>
        /// <returns></returns>
        public bool DisConnect(out string errorMsg)
        {
            errorMsg = string.Empty;
            bool result = false;
            try
            {
                if (Client.Connected)
                {
                    // 关闭 Socket 连接，释放连接相关资源
                    Client.Close();
                    // 释放 Socket 对象本身占用的非托管资源
                    Client.Dispose();
                    result = true;
                }
            }
            catch (Exception ex)
            {
                errorMsg = ex.Message;
            }
            return result;
        }

        public override byte[] ReadCoilInput(byte slaveId, ushort startAddress, ushort coilNums, out bool result, out string errorMsg, int timeout = 100, int readCount = 1)
        {
            throw new NotImplementedException();
        }

        public override byte[] ReadCoilOuput(byte slaveId, ushort startAddress, ushort coilNums, out bool result, out string errorMsg, int timeout = 100, int readCount = 1)
        {
            throw new NotImplementedException();
        }

        public override byte[] ReadHoldRegister_Byte(byte slaveId, ushort registerAddress, ushort registerNums, out bool result, out string errorMsg, int timeout = 100, int readCount = 1)
        {
            throw new NotImplementedException();
        }

        public override byte[] ReadiInputRegister_Byte(byte slaveId, ushort registerAddress, ushort registerNums, out bool result, out string errorMsg, int timeout = 100, int readCount = 1)
        {
            throw new NotImplementedException();
        }

        public override bool WriteMulitpleHoldRegister_Byte(byte slaveId, ushort registerAddress, byte[] registerValue, out string errorMsg, int timeout = 100, int writeCount = 1)
        {
            throw new NotImplementedException();
        }

        public override bool WriteMultipleCoil(byte slaveId, ushort registerAddress, byte[] coilStatusVal, out string errorMsg, int timeout = 100, int writeCount = 1)
        {
            throw new NotImplementedException();
        }

        public override bool WriteSingleCoil(byte slaveId, ushort registerAddress, bool isOn, out string errorMsg, int timeout = 100, int writeCount = 1)
        {
            throw new NotImplementedException();
        }

        public override bool WriteSingleHoldRegister(byte slaveId, ushort registerAddress, ushort registerValue, out string errorMsg, int timeout = 100, int writeCount = 1)
        {
            throw new NotImplementedException();
        }
    }
}
